/**
 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef ECMASCRIPT_IC_PROTOTYPE_CHANGE_DETAILS_H
#define ECMASCRIPT_IC_PROTOTYPE_CHANGE_DETAILS_H

#include "plugins/ecmascript/runtime/ecma_macros.h"
#include "plugins/ecmascript/runtime/js_handle.h"
#include "plugins/ecmascript/runtime/js_tagged_value.h"
#include "plugins/ecmascript/runtime/weak_vector.h"

namespace ark::ecmascript {
class ProtoChangeMarker : public TaggedObject {
public:
    using HasChangedField = BitField<bool, 0, 1>;
    static ProtoChangeMarker *Cast(ObjectHeader *object)
    {
        ASSERT(JSTaggedValue(object).IsProtoChangeMarker());
        return static_cast<ProtoChangeMarker *>(object);
    }

    ACCESSORS_START(TaggedObjectSize())
    ACCESSORS_PRIMITIVE_FIELD(0, HasChanged, bool)
    ACCESSORS_FINISH(1)
    DECL_DUMP()
};

class ProtoChangeDetails : public TaggedObject {
public:
    static constexpr int UNREGISTERED = -1;
    static ProtoChangeDetails *Cast(ObjectHeader *object)
    {
        ASSERT(JSTaggedValue(object).IsProtoChangeDetails());
        return static_cast<ProtoChangeDetails *>(object);
    }

    ACCESSORS_START(TaggedObjectSize())
    ACCESSORS(0, ChangeListener)
    ACCESSORS(1, RegisterIndex)
    ACCESSORS_FINISH(2)

    DECL_DUMP()
};

class ChangeListener : public WeakVector {
public:
    static ChangeListener *Cast(ObjectHeader *object)
    {
        return static_cast<ChangeListener *>(object);
    }

    static JSHandle<ChangeListener> Add(const JSThread *thread, const JSHandle<ChangeListener> &array,
                                        const JSHandle<JSHClass> &value, uint32_t *index);

    static uint32_t CheckHole(const JSHandle<ChangeListener> &array);

    JSTaggedValue Get(uint32_t index);
};
}  // namespace ark::ecmascript

#endif  // ECMASCRIPT_IC_PROTOTYPE_CHANGE_DETAILS_H
